home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 276-300 / 299 / rxil / src / init.c < prev    next >
C/C++ Source or Header  |  1995-03-14  |  5KB  |  225 lines

  1. /* init.c */
  2.  
  3. /*        Copyright © 1989 by Donald T. Meyer, Stormgate Software
  4.  *        All Rights Reserved
  5.  */
  6.  
  7.  
  8.  
  9. #include "rxil.h"
  10.  
  11. #include <exec/memory.h>
  12.  
  13. #include <string.h>
  14.  
  15.  
  16.  
  17. static void unique_name( char portname[] );
  18.  
  19. struct RxsLib *RexxSysBase = NULL;
  20.  
  21. static char library_version_string[] = RXIL_VERSION_STRING;
  22.  
  23.  
  24.  
  25. /* NAME
  26.  *        RxilInit
  27.  *
  28.  * SYNOPSIS
  29.  *        rdef = RxilInit( flags, portname );
  30.  *
  31.  *        struct RxilDef *rdef;
  32.  *
  33.  *        ULONG flags;
  34.  *        char *portname;
  35.  *
  36.  * FUNCTION
  37.  *        Open the ARexx library and setup our message ports.  Then
  38.  *        allocate a RxilDef structure and do some default initialization
  39.  *        of it.
  40.  *        The portname will have a unique "instance" number appended
  41.  *        to it in the format "<name>_#<n>" where <name> is the string as
  42.  *        specified in the portname argument, and <n> is a decimal number
  43.  *        from 1-99 inclusive.  This feature may be inhibited by setting
  44.  *        the RXIL_AS_IS flag.
  45.  *
  46.  *        Even though this may fail, that should probably not be fatal
  47.  *        since the ARexx functionality is optional.  The RxilCheckPort()
  48.  *        function is smart enough to just return if the rexx initialization
  49.  *        was not successsfull.  Not to mention that RxilCheckPort() should
  50.  *        never get called since the rexx_sig_bit mask should be zero.
  51.  *
  52.  * INPUTS
  53.  *        flags        These are various defined constants which control
  54.  *                    which ports get opened and other various aspects
  55.  *                    of port initialization.
  56.  *
  57.  *        portname    This is the name to use for the public ARexx port
  58.  *                    that commands will be received at.  It is suggested
  59.  *                    that this be in uppercase and contain no spaces.
  60.  *                    Maximum length is 40 characters, as set by the
  61.  *                    defined constant RXIL_MAX_PORTNAME_LEN.
  62.  *                    See discussion above about instance numbers.
  63.  *
  64.  * RESULT
  65.  *        A pointer to a RxilDef structure.  Return is NULL for failure
  66.  *        to initialize the ARexx ports.
  67.  *
  68.  * SIDES
  69.  *
  70.  * HISTORY
  71.  *        01-Aug-89    Creation.
  72.  *        23-Sep-89    Changed "flags" arg from int to ULONG
  73.  *        26-Sep-89    Sets the (new) version string pointer.
  74.  *        01-Oct-89    Changed PublicPort name storage from a pointer to
  75.  *                    a character array.  Added "instance" numbering.
  76.  *                    Added check on portname length.
  77.  *
  78.  * BUGS
  79.  *         This should probably share one signal bit between both ports
  80.  *        to avoid "hogging" signal bits.
  81.  *
  82.  * SEE ALSO
  83.  *        RxilCleanup(), RXIL_AS_IS, RXIL_MAX_PORTNAME_LEN
  84.  */
  85.  
  86. struct RxilDef *RxilInit( ULONG flags, char *portname )
  87. {
  88.     char buf[24];
  89.     struct RxilDef *rdef;
  90.  
  91.  
  92.     if(  ( strlen(portname) < 1 ) ||
  93.         ( strlen(portname) > RXIL_MAX_PORTNAME_LEN )  )
  94.     {
  95.         /* Portname is of an invalid length */
  96.         return( NULL );
  97.     }
  98.  
  99.  
  100.     rdef = AllocMem( sizeof(struct RxilDef), MEMF_PUBLIC | MEMF_CLEAR );
  101.     if( rdef == NULL )
  102.     {
  103.         return( NULL );
  104.     }
  105.  
  106.  
  107.     /* Default initialization of the new RxilDef structure */
  108.  
  109.     rdef->Console = NULL;
  110.     rdef->Extension = "rexx";
  111.     rdef->HostPort = "REXX";
  112.  
  113.  
  114.     strcpy( rdef->PortName, portname );
  115.     if(  FlagIsClear( flags, RXIL_AS_IS )  )
  116.     {
  117.         /* Make sure the public port name is unique */
  118.         unique_name( rdef->PortName );
  119.     }
  120.  
  121.     /*   Open Rexx library   */
  122.     RexxSysBase = (struct RxsLib *)OpenLibrary( RXSNAME, 0L );
  123.     if( RexxSysBase == NULL )
  124.     {
  125.         FreeMem( rdef, sizeof(struct RxilDef) );
  126.         return( NULL );
  127.     }
  128.  
  129.  
  130.     if(  FlagIsSet( flags, RXIL_PUBLIC )  )
  131.     {
  132.         /* Setup our public port */
  133.  
  134.         rdef->PublicPort = CreatePort( rdef->PortName, 1L );
  135.         if( rdef->PublicPort == NULL )
  136.         {
  137.             CloseLibrary( (struct Library *)RexxSysBase );
  138.             RexxSysBase = NULL;
  139.             FreeMem( rdef, sizeof(struct RxilDef) );
  140.             return( NULL );
  141.         }
  142.  
  143.         rdef->SigBit |= 1L << (rdef->PublicPort->mp_SigBit);
  144.     }
  145.  
  146.  
  147.     if(  FlagIsSet( flags, RXIL_SECRET )  )
  148.     {
  149.         /* Setup our secret port */
  150.         strcpy( rdef->SecretPortName, rdef->PortName );
  151.         strcat( rdef->SecretPortName, "_PRIVATE_" );
  152.         stcul_d( buf, (long)FindTask(NULL) );
  153.         strcat( rdef->SecretPortName, buf );
  154.  
  155.         rdef->SecretPort = CreatePort( rdef->SecretPortName, 1L );
  156.         if( rdef->SecretPort == NULL )
  157.         {
  158.             /* Failure */
  159.             if( rdef->PublicPort )
  160.             {
  161.                 RxilDeletePort( rdef->PublicPort );
  162.                 rdef->PublicPort = NULL;
  163.             }
  164.  
  165.             CloseLibrary( (struct Library *)RexxSysBase );
  166.             RexxSysBase = NULL;
  167.  
  168.             rdef->SigBit = 0;
  169.  
  170.             FreeMem( rdef, sizeof(struct RxilDef) );
  171.  
  172.             return( NULL );
  173.         }
  174.  
  175.         rdef->SigBit |= 1L << (rdef->SecretPort->mp_SigBit);
  176.     }
  177.  
  178.  
  179.     /* Set the version string pointer. */
  180.     rdef->Version = &library_version_string[0];
  181.  
  182.  
  183.     return( rdef );
  184. }
  185.  
  186.  
  187.  
  188. /*
  189.  *        This will take the port name in the buffer, and add a sequential
  190.  *        invocation number to it to insure uniqueness.
  191.  *
  192.  *        Note that this will increase the length of the given string!
  193.  *        Make sure that the buffer is at least 4 characters longer than
  194.  *        the original string.
  195.  */
  196.  
  197. static void unique_name( char portname[] )
  198. {
  199.     char buf[RXIL_MAX_PORTNAME_LEN+10], buf2[4];
  200.     unsigned int i;
  201.  
  202.  
  203.     for( i=1; i<100; i++ )
  204.     {
  205.         strcpy( buf, portname );        /* Orig. name "APP" (example) */
  206.         strcat( buf, "_#" );            /* "APP_#" */
  207.         stcu_d( buf2, i );
  208.         strcat( buf, buf2 );            /* "APP_#1" */
  209.  
  210.         if(  FindPort( buf ) == NULL  )
  211.         {
  212.             /* Okay, this name does not exist.  Let's use it. */
  213.             strcpy( portname, buf );
  214.             return;
  215.         }
  216.     }
  217.  
  218.  
  219.     /* Amazing!  If we actually get here, there are already 99 instances
  220.      * of this program running.  I cannot imagine ever getting here. :-)
  221.      * If we do, then I guess we'll just collide...
  222.      */
  223. }
  224.  
  225.